﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using VAdvantage.Classes;
using VAdvantage.Model;
using System.Data;
using PdfSharp.Drawing;
using System.Text;
using VAdvantage.Utility;
using VAdvantage.Logging;

namespace VAdvantage.Print
{
    public class MPrintFont : X_AD_PrintFont
    {
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="AD_PrintFont_ID">AD_PrintFont_ID</param>
        /// <param name="trxName">transaction</param>
        public MPrintFont(Context ctx, int AD_PrintFont_ID, String trxName)
            : base(ctx, AD_PrintFont_ID, trxName)
        {

            if (AD_PrintFont_ID == 0)
                SetIsDefault(false);
        }	//	MPrintFont

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="rs">datarow</param>
        /// <param name="trxName">transaction</param>
        public MPrintFont(Context ctx, DataRow rs, String trxName)
            : base(ctx, rs, trxName)
        {
        }	//	MPrintFont

        /** Font cached					*/
        private XFont _cacheFont = null;
        private const float JAVA_COMPATIBLE = 0.0f;

        public XFont GetFont()
        {
            if (_cacheFont != null)
                return _cacheFont;
            String code = (String)Get_Value("Code");
            int pos = code.LastIndexOf("-");
            int size = Convert.ToInt32(code.Substring(pos + 1));
            if (code == null || code.Equals("."))
                _cacheFont = new XFont("sansserif", size - JAVA_COMPATIBLE, XFontStyle.Regular);
            try
            {
                if (code != null && !code.Equals("."))
                //	fontfamilyname-style-pointsize
                {
                    _cacheFont = Decode(code);
                }
            }
            catch (Exception e)
            {
                log.Log(Level.SEVERE, "Code=" + code, e);
            }
            if (code == null)
                _cacheFont = null;
            //	family=dialog,name=Dialog,style=plain,size=12
            //	//log.fine(code + " - " + m_cacheFont);
            return _cacheFont;
        }	//	getFont


        /// <summary>
        /// Decode the font string saved in database
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public XFont Decode(string str)
        {
            String fontName = str;
            String styleName = "";
            //int pos = str.LastIndexOf("-");
            //int fontSize = Convert.ToInt32(str.Substring(pos + 1)) - 2;
            int fontSize = 12;
            XFontStyle fontStyle = XFontStyle.Regular;

            if (str == null)
            {
                return new XFont("Dialog", fontSize, fontStyle);
            }

            int lastHyphen = str.LastIndexOf('-');
            int lastSpace = str.LastIndexOf(' ');
            char sepChar = (lastHyphen > lastSpace) ? '-' : ' ';
            int sizeIndex = str.LastIndexOf(sepChar);
            int styleIndex = str.LastIndexOf(sepChar, sizeIndex - 1);
            int strlen = str.Length;

            if (sizeIndex > 0 && sizeIndex + 1 < strlen)
            {
                try
                {
                    fontSize = int.Parse(str.Substring(sizeIndex + 1));
                    if (fontSize <= 0)
                    {
                        fontSize = 12;
                    }
                }
                catch (Exception e)
                {
                    /* It wasn't a valid size, if we didn't also find the
                     * start of the style string perhaps this is the style */
                    styleIndex = sizeIndex;
                    sizeIndex = strlen;
                    if (str[sizeIndex - 1] == sepChar)
                    {
                        sizeIndex--;
                    }
                }
            }

            if (styleIndex >= 0 && styleIndex + 1 < strlen)
            {
                styleName = str.Substring(styleIndex + 1, sizeIndex - (styleIndex + 1));
                styleName = styleName.ToLower();
                if (styleName.Equals("bolditalic"))
                {
                    fontStyle = XFontStyle.Bold | XFontStyle.Italic;
                }
                else if (styleName.Equals("italic"))
                {
                    fontStyle = XFontStyle.Italic;
                }
                else if (styleName.Equals("bold"))
                {
                    fontStyle = XFontStyle.Bold;
                }
                else if (styleName.Equals("plain"))
                {
                    fontStyle = XFontStyle.Regular;
                }
                else
                {
                    /* this string isn't any of the expected styles, so
                     * assume its part of the font name
                     */
                    styleIndex = sizeIndex;
                    if (str[styleIndex - 1] == sepChar)
                    {
                        styleIndex--;
                    }
                }
                fontName = str.Substring(0, styleIndex);

            }
            else
            {
                int fontEnd = strlen;
                if (styleIndex > 0)
                {
                    fontEnd = styleIndex;
                }
                else if (sizeIndex > 0)
                {
                    fontEnd = sizeIndex;
                }
                if (fontEnd > 0 && str[fontEnd - 1] == sepChar)
                {
                    fontEnd--;
                }
                fontName = str.Substring(0, fontEnd);
            }

            if (fontName == "serif")
            {
                //return new XFont(XFontFamily, fontSize - JAVA_COMPATIBLE, fontStyle);
            }
            {
                return new XFont(fontName, fontSize - JAVA_COMPATIBLE, fontStyle);
            }
        }

        public void SetFont(XFont font)
        {
            //	fontfamilyname-style-pointsize
            StringBuilder sb = new StringBuilder();
            sb.Append(font.FontFamily.ToString()).Append("-");
            XFontStyle style = font.Style;
            if (style == XFontStyle.Regular)
                sb.Append("PLAIN");
            else if (style == XFontStyle.Bold)
                sb.Append("BOLD");
            else if (style == XFontStyle.Italic)
                sb.Append("ITALIC");
            else if (style == (XFontStyle.Bold | XFontStyle.Italic))
                sb.Append("BOLDITALIC");
            sb.Append("-").Append(font.Size.ToString());
            SetCode(sb.ToString());
        }	//	setFont


        public static MPrintFont Create(XFont font)
        {
            MPrintFont pf = new MPrintFont(Envs.GetContext(), 0, null);
            StringBuilder name = new StringBuilder(font.Name);
            if (font.Style == XFontStyle.Bold)
                name.Append(" bold");
            if (font.Style == XFontStyle.Italic)
                name.Append(" italic");
            name.Append(" ").Append(font.Size);
            pf.SetName(name.ToString());
            pf.SetFont(font);
            pf.Save();
            return pf;
        }	//	create


        /** Cached Fonts						*/
        static private CCache<int, MPrintFont> _fonts = new CCache<int, MPrintFont>("AD_PrintFont", 20);

        static public MPrintFont Get(int AD_PrintFont_ID)
        {
            int key = AD_PrintFont_ID;
            MPrintFont pf = (MPrintFont)_fonts[key];
            if (pf == null)
            {
                pf = new MPrintFont(Envs.GetContext(), AD_PrintFont_ID, null);
                _fonts.Add(key, pf);
            }
            return pf;
        }	//	get
    }
}
